package com.run.bluetoothconnect;

import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class BluetoothServerActivity extends BaseActivity {

    //线程池
    private final ExecutorService threadPool = Executors.newCachedThreadPool();

    private BluetoothAdapter mBluetoothAdapter;

    private BluetoothServerSocket serverSocket;

    private EditText sendText;
    private Button sendButton;
    private TextView receiveText;

    //选中设备
    private TextView selectText;
    //选折全部按钮
    private Button selectAllButton;
    //选中下标，-1表示全部
    private int selectIndex = -1;

    private RecyclerView recyclerView;
    private BaseRecyclerAdapter<BluetoothSocket> adapter;
    private final List<BluetoothSocket> bluetoothSockets = new CopyOnWriteArrayList<>();

    private final String tag = "蓝牙调试";
    private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";

    //服务端线程
    private class ServerThread implements Runnable {

        private final BluetoothSocket remotePeer;
        private final String deviceName;

        private ServerThread(BluetoothSocket remotePeer) {
            this.remotePeer = remotePeer;
            deviceName = remotePeer.getRemoteDevice().getName();
        }

        @Override
        public void run() {
            try {
                InputStream inputStream;
                while(remotePeer != null && remotePeer.isConnected()) {

                    //简单写写
                    inputStream = remotePeer.getInputStream();
                    byte[] buffer = new byte[2560];
                    int len = inputStream.read(buffer, 0, 2560);
                    if (len <= 0) {
                        //noinspection BusyWait
                        Thread.sleep(1000);
                        continue;
                    }

                    //打印接收消息
                    runOnUiThread(()->receiveText.append("收到消息->" + deviceName + ":\n\t\t\t\t"
                            + new String(buffer, 0, len) + "\n"));
                }
            } catch(IOException e) {
                e.printStackTrace();
            } catch(Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if (null != remotePeer) {
                        remotePeer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void initParams(Bundle params) {
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    @Override
    public int bindLayout() {
        return R.layout.activity_bluetooth_server;
    }

    @Override
    public void initView(View view) {
        sendText = $(R.id.input);
        sendButton = $(R.id.send);
        receiveText = $(R.id.receive);

        selectText = $(R.id.select);
        selectAllButton = $(R.id.all);

        recyclerView = $(R.id.recycler);
    }

    @Override
    public void initData() {

    }

    @Override
    public void doBusiness(Context mContext) {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        receiveText.setText("等待客户端连接...\n");

        //启动服务端
        if (mBluetoothAdapter != null) {
            threadPool.execute(new Thread(() -> {
                try {
                    serverSocket = mBluetoothAdapter
                            .listenUsingRfcommWithServiceRecord(tag, UUID.fromString(MY_UUID));
                    while (true) {
                        BluetoothSocket remotePeer = serverSocket.accept();

                        bluetoothSockets.add(remotePeer);
                        runOnUiThread(()->adapter.notifyDataSetChanged());

                        //获取蓝牙设备
                        BluetoothDevice device = remotePeer.getRemoteDevice();
                        runOnUiThread(()->receiveText.append("连接客户端成功:" + device.getName() + "\n"));

                        //启动线程处理socket连接
                        threadPool.execute(new ServerThread(remotePeer));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }));
        }

        //列表相关
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.addItemDecoration(
                new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
        //设置适配器
        adapter = new BaseRecyclerAdapter<BluetoothSocket>(
                android.R.layout.simple_list_item_1, bluetoothSockets
        ) {
            @Override
            public void convertView(ViewHolder viewHolder, BluetoothSocket socket, int position) {
                viewHolder.setText(android.R.id.text1, socket.getRemoteDevice().getName());
            }
        };
        //设置点击事件
        adapter.setOnItemClickListener((view1, socket, position) -> new AlertDialog.Builder(this)
                .setTitle("客户端操作")
                .setMessage("是否向" + socket.getRemoteDevice().getName() + "发送消息？")
                .setPositiveButton("是", (dialog, which) -> {
                    selectIndex = position;
                    selectText.setText(socket.getRemoteDevice().getName());
                })
                .setNeutralButton("断开连接", (dialog, which) -> {
                    String deviceName = socket.getRemoteDevice().getName();
                    //断开该连接
                    try {
                        socket.close();

                        //移除断开设备
                        bluetoothSockets.remove(socket);
                        adapter.notifyDataSetChanged();

                        runOnUiThread(()->receiveText.append("断开连接成功：" + deviceName + "\n"));
                    } catch (IOException e) {
                        e.printStackTrace();
                        runOnUiThread(()->receiveText.append("断开连接失败：" + deviceName + "\n"));
                    }
                })
                .setNegativeButton("否", null)
                .create()
                .show());
        recyclerView.setAdapter(adapter);

        //选择向全部设备发送消息
        selectAllButton.setOnClickListener(v -> new AlertDialog.Builder(this)
                .setTitle("")
                .setMessage("是否向所有设备发送消息？")
                .setPositiveButton("是", (dialog, which) -> {
                    selectIndex = -1;
                    selectText.setText("全部");
                })
                .setNegativeButton("否", null)
                .create()
                .show());

        //发送消息按钮
        sendButton.setOnClickListener(v -> {
            String data = sendText.getText().toString();
            if (!TextUtils.isEmpty(data)) {
                if (selectIndex < 0) {
                    //遍历向所有客户端发送数据
                    for (BluetoothSocket socket : bluetoothSockets) {
                        sendDataToClient(socket, data);
                    }
                }else {
                    //向单个蓝牙设备发送数据
                    BluetoothSocket socket = bluetoothSockets.get(selectIndex);
                    sendDataToClient(socket, data);
                }
            }
        });
    }

    //向指定客户端socket发送消息
    private void sendDataToClient(BluetoothSocket socket, String data) {
        String deviceName = null != socket ? socket.getRemoteDevice().getName() : null;
        if (null != socket && socket.isConnected()) {
            //异步线程发送
            threadPool.execute(() -> {
                try {
                    socket.getOutputStream().write(data.getBytes());
                    runOnUiThread(()->receiveText.append("发送消息->" + deviceName
                            + ":\n\t\t\t\t" + data + "\n"));
                } catch (IOException e) {
                    runOnUiThread(()->receiveText.append("发送消息->" + deviceName + ":" + "失败！"
                            + e.getMessage() + "\n"));
                    e.printStackTrace();
                }
            });
        }else {
            runOnUiThread(()->receiveText.append("发送消息->" + deviceName + ":" + "失败！" + "\n"));
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            for (BluetoothSocket socket : bluetoothSockets) {
                socket.close();
            }
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
